/*
 * alternateStyle.js
 * Copyright (C) 2005-2006 David Stone
 * 
 * Licensed under the terms of the GNU Lesser General Public License:
 * 		http://www.opensource.org/licenses/lgpl-license.php
 * 
 * For further information visit: http://www.builtbydave.co.uk/
 * 
 */

/* for IE5, and any other browser that doesn't support Array.push()  */
if (typeof Array.prototype.push=='undefined')
{
	Array.prototype.push = function() {
		var a = arguments;
		var b = this.length;
		for(var i=0;i<a.length;i++)
			this[b+i]=a[i];
		return this.length
	};
}

/* Yes, I know this isn't the *best* uses of objects */
function alternateStyles()
{
}

alternateStyles.prototype.styles = new Array();
alternateStyles.prototype.debugLog = 'DEBUG LOG:\n';
alternateStyles.prototype.cookieName = 'alternateStyles';
alternateStyles.prototype.cookieDomain = document.location['host'];
alternateStyles.prototype.cookieExpires = "Thu, 01-Jan-2070 00:00:01 GMT";
alternateStyles.prototype.cookiePath = '';
alternateStyles.prototype.cookieSecure = false;

/* oh, yay, we really need this! */
alternateStyles.prototype.toString = function()
{
	return "[object alternateStyles]";
}

/* add a style for this user on a specific dom element */
alternateStyles.prototype.addStyle = function(dom,css)
{
	this.removeStyles(dom);
	this.styles.push(new Array(dom,css));
}

/* remove all styles set in alternateStyles.js on this element */
alternateStyles.prototype.removeStyles = function(dom)
{
	if (this.styles.length==0)
		return;
	var i = 0;
	var j = this.styles.length;

	/* can't slice the array with one result, so just check before loop */
	if (this.styles.length==1 && this.styles[0][0]==dom)
	{
		this.styles = new Array();
		return true;
	}
	
	/* loop to check removal of all dom elements */
	while (i<j)
	{
		if (this.styles[i][0]==dom)
		{
			this.styles.slice(0,i).concat(this.styles.slice(i+1,this.styles.length));
			j--;
		}
		i++;
	}
}

/* sets multiple styles to an object */
alternateStyles.prototype.setCss = function(object,styles)
{
	var css = styles.split(';');
	for (var i=0;i<css.length-1;i++)
	{
		var s = css[i].split(':');
		var propertyName = s[0].replace(/^\s*|\s*$/g,"");
		if (object.style.setProperty==null || object.style.setProperty=='undefined')
		{
			/* rebuild style name */
			var propertyName = '';
			for(var i;i<s[0].length;i++)
			{
				var letter = s[0].charAt(i);
				if (letter=='-')
				{
					letter = ''; /* remove spaces */
					propertyName+= s[0].charAt(i+1).toUpperCase(); /* make next letter upper case */
					i++;
				}
				propertyName+= letter;
			}
			s[0] = propertyName;
			object.style[propertyName] = s[1];
		}
		else
		{
			object.style.setProperty(s[0].replace(/^\s*|\s*$/g,""),s[1],null);
		}
	}
}

/* save user styles to cookie for loading later */
alternateStyles.prototype.save = function()
{
	document.cookie = this.cookieName + "=" + escape(this.styles) +
		((this.cookieExpires) ? "; expires=" + this.cookieExpires : "") +
		((this.cookiePath) ? "; path=" + this.cookiePath : "") +
		((this.cookieDomain) ? "; domain=" + this.cookieDomain : "") +
		((this.cookieSecure) ? "; secure" : "");
	if (this.getStyles()==this.styles)
		return true;
	else
		return false;
}

/* empty this.styles and the cookie */
alternateStyles.prototype.empty = function()
{
	this.styles = new Array;
	return this.save();
}

/* save and load again */
alternateStyles.prototype.saveAndReload = function()
{
	var s = this.save();
	var l = this.load(); /* TODO: check is successful */
	if (s==true)
		return true;
}

/* get styles from cookie */
alternateStyles.prototype.getStyles = function()
{
	var cookies = document.cookie.split(';');
	for(var i=0;i<cookies.length;i++)
	{
		var cookie = cookies[i];
		var cookieDetails = cookie.split('=');
		if (cookieDetails[0].replace(/^\s*|\s*$/g,"")==this.cookieName)
			return unescape(cookieDetails[1]);
	}
}

/* get styles from cookie and parse */
alternateStyles.prototype.load = function()
{
	var styles = this.getStyles();
	this.debugLog += "Got Styles: "+styles+"\n";
	if (styles!=null)
	{
		var css = styles.split(',');
		for (var i=0;i<css.length;i++)
		{
			if ((i/2).toString().indexOf('.')==-1)
			{
				this.parseDom(css[i],css[i+1]);
			}
		}
	}
}

/* parses the DOM to find the element(s) to change  */
alternateStyles.prototype.parseDom = function(elem,style)
{
	var items = document.getElementsBySelector(elem);
	for (var i=0;i<items.length;i++)
	{
		this.setCss(items[i],style);
	}
}

